class IUP_FLAT_TOGGLE
-- Creates an interface element that is a toggle, but it does not have native 
-- decorations. When selected, this element activates a function in the 
-- application. Its visual presentation can contain a text and/or an image.
--
-- It behaves just like an IUP_TOGGLE, but since it is not a native control it 
-- has more flexibility for additional options.
--
-- It inherits from IUP_CANVAS.
--
-- Notes:
--
-- The IUP_FLAT_TOGGLE can contain the check box, text and image simultaneously.
--
-- The natural size will be a combination of the size of the image and the 
-- title, if any, plus PADDING and SPACING (if both image and title are 
-- present), and the check box if visible.
--
-- Borders are drawn only when the button is highlighted reproducing the 
-- behavior of the IUP_BUTTON when FLAT=True. When the check box is shown the 
-- borders are not shown, and the background is not highlighted.
--
-- Buttons are activated using Enter or Space keys.
--
-- To build a set of mutual exclusive toggles, insert them in a IUP_RADIO 
-- container. They must be inserted before creation, and their behavior can not 
-- be changed.
--
-- The toggle that is a child of an IUP_RADIO automatically receives a name 
-- when its is mapped into the native system.
--
-- When the IUP_FLAT_TOGGLE displays only a text it will look like a label, use 
-- set_show_border=True to force the display of the borders all the time.
	
inherit
	IUP_CANVAS
		redefine
			set_border,
			set_can_focus,
			set_expand,
			execute_flat_action,
			execute_flat_button,
			execute_flat_focus,
			execute_flat_enterwindow,
			execute_flat_leavewindow,
			execute_valuechanged
		end
	IUP_WIDGET_FGCOLOR
	IUP_WIDGET_SPACING
	IUP_WIDGET_TITLE
	IUP_WIDGET_FLAT_TEXT
		redefine
			set_alignment
		end
	IUP_WIDGET_BACK_IMAGE_2
	IUP_WIDGET_FRONT_IMAGE_2
	IUP_WIDGET_IMAGE_2
	IUP_WIDGET_PADDING
	IUP_WIDGET_BORDER
	IUP_WIDGET_HAS_FOCUS
	IUP_WIDGET_HIGHLIGHT
	IUP_WIDGET_PRESS
	IUP_WIDGET_IGNORERADIO
	IUP_WIDGET_FOCUSFEEDBACK
	IUP_WIDGET_TOGGLE

create {ANY}
	flat_toggle_empty,
	flat_toggle

feature {ANY}

	flat_toggle_empty
		local
			a_flat_toggle, p: POINTER
		do
			a_flat_toggle := int_flat_toggle(p)
			
			set_widget(a_flat_toggle)
		end

	flat_toggle (text: STRING)
		local
			a_flat_toggle: POINTER
		do
			a_flat_toggle := int_flat_toggle(text.to_external)
			
			set_widget(a_flat_toggle)
		end

	-- Attributes

	set_alignment (horizontal, vertical: STRING)
		-- (non inheritable): horizontal and vertical alignment of the set 
		-- image+text. Possible values: "ALEFT", "ACENTER" and "ARIGHT", combined 
		-- to "ATOP", "ACENTER" and "ABOTTOM". Default: "ACENTER:ACENTER". 
		-- Alignment does not includes the padding area. 
		do
			Precursor (horizontal, vertical)
		end

	set_border (state: BOOLEAN)
		-- (creation only): Shows a border around the canvas. Default: "False".
		do
			Precursor (state)
		end

	set_can_focus (state: BOOLEAN)
		-- (creation only) (non inheritable): enables the focus traversal of the 
		-- control. In Windows the button will respect CANFOCUS in opposite to 
		-- the other controls. Default: True.
		do
			Precursor (state)
		end

	set_check_size (value: INTEGER)
		-- (non inheritable): size of the check box when visible. Default depends 
		-- on the resolution: 16 (dpi <= 120), or 24 (dpi > 120). Set it to 0 to 
		-- hide the check box. When the check box is shown the borders are not 
		-- shown, and the background is not highlighted.
		require
			value > -1
		do
			iup_open.set_attribute(Current, "CHECKSIZE", value.to_string)
		end

	set_check_at_right (state: BOOLEAN)
		-- (non inheritable): place the check box at the right. Default: "False".
		do
			iup_open.set_attribute(Current, "CHECKRIGHT", boolean_to_yesno(state))
		end

	set_check_spacing (value: INTEGER)
		-- (non inheritable): spacing between the check box and the image+text. 
		-- The space occupies the image+text area. Default: 5
		require
			value > -1
		do
			iup_open.set_attribute(Current, "CHECKSPACING", value.to_string)
		end

	set_check_alignment (value: STRING)
		-- (non inheritable): vertical alignment of the check box. Can be "ATOP", 
		-- "ACENTER" and "ABOTTOM". Default: ACENTER.
		require
			is_valid_vertical_alignment(value)
		do
			iup_open.set_attribute(Current, "CHECKALIGN", value)
		end

	set_chek_image (name: STRING)
		-- (non inheritable): image name to be used as check box when value is 
		-- OFF, be sure the image size is equal to CHECKSIZE-2. If this attribute 
		-- is defined the check box is not drawn, the images will be used instead.
		do
			iup_open.set_attribute(Current, "CHECKIMAGE", name)
		end

	set_check_image_highlight (name: STRING)
		-- (non inheritable): check box image name of the element in highlight 
		-- state when value os OFF. If it is not defined then the CHECKIMAGE is 
		-- used.	
		do
			iup_open.set_attribute(Current, "CHECKIMAGEHIGHLIGHT", name)
		end

	set_check_image_inactive (name: STRING)
		-- (non inheritable): check box image name of the element when inactive 
		-- and value is OFF. If it is not defined then the CHECKIMAGE is used and 
		-- its colors will be replaced by a modified version creating the 
		-- disabled	effect.
		do
			iup_open.set_attribute(Current, "CHECKIMAGEINACTIVE", name)
		end

	set_check_image_press (name: STRING)
		-- (non inheritable): check box image name of the element in pressed 
		-- state when value is OFF. If it is not defined then the CHECKIMAGE is 
		-- used.	
		do
			iup_open.set_attribute(Current, "CHECKIMAGEPRESS", name)
		end

	set_check_image_on (name: STRING)
		-- (non inheritable): (non inheritable): image name to be used as check 
		-- box when value is ON.
		do
			iup_open.set_attribute(Current, "CHECKIMAGEON*", name)
		end

	set_check_image_not_def (name: STRING)
		-- (non inheritable): (non inheritable): image name to be used as check 
		-- box when value is NOTDEF.
		do
			iup_open.set_attribute(Current, "CHECKIMAGENOTDEF*", name)
		end

	set_expand (type: STRING)
		-- (non inheritable): The default value is "False".
		do
			Precursor (type)
		end

	is_radio: BOOLEAN
		-- (read-only): returns if the toggle is inside a radio.
		local
			str: STRING
		do
			str := iup_open.get_attribute(Current, "RADIO")
			Result := yesno_to_boolean(str)
		end

	set_value (value: STRING)
		-- (non inheritable): Toggle's state. Values can be "ON" or "OFF". If 
		-- 3state=True then can also be "NOTDEF". Default: "OFF". Can only be set 
		-- to ON for a toggle inside a radio, it will automatically set to OFF 
		-- the previous toggle that was ON.
		require
			is_valid_state(value)
		do
			iup_open.set_attribute(Current, "VALUE", value)
		end

	get_value: STRING
		do
			Result := iup_open.get_attribute(Current, "VALUE")
		end

	set_3state (state: BOOLEAN)
		-- (creation only): Enable a three state toggle. Valid for toggles with 
		-- text only and that do not belong to a radio. Default: "False".
		do
			iup_open.set_attribute(Current, "3STATE", boolean_to_yesno(state))
		end

	-- Operations

	invert
		-- Invert the current state.
		do
			iup_open.set_attribute(Current, "VALUE", "TOGGLE")
		end

	-- Extra callbacks

	set_cb_flat_action (act: FUNCTION[TUPLE[IUP_FLAT_TOGGLE], STRING])
		-- Action generated when the button 1 (usually left) is selected. This 
		-- callback is called only after the mouse is released and when it is 
		-- released inside the button area. Called only when 
		-- set_drop_on_arrow=True
		--
		--	ih: identifier of the element that activated the event.
		--
		-- Returns: IUP_CLOSE will be processed.
		local
			operation: INTEGER
		do
			cb_flat_action := act

			if cb_flat_action /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "FLAT_ACTION", "Fnff", operation)
		end

	set_cb_value_changed (act: FUNCTION[TUPLE[IUP_FLAT_TOGGLE], STRING])
		-- Called after the value was interactively changed by the user.
		local
			operation: INTEGER
		do
			cb_valuechanged := act

			if cb_valuechanged /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "VALUECHANGED_CB", "NONEEDED", operation)
		end

	----------------------

	set_cb_flat_button (act: FUNCTION[TUPLE[IUP_FLAT_TOGGLE, INTEGER, INTEGER, INTEGER, INTEGER, STRING], STRING])
		-- Action generated when any mouse button is pressed and when it is 
		-- released. Both calls occur before the ACTION callback when button 1 is 
		-- being used.
		-- IUP_CANVAS: identifies the element that activated the event.
		-- button: identifies the activated mouse button:
		--
		-- 1 - left mouse button (button 1);
		-- 2 - middle mouse button (button 2);
		-- 3 - right mouse button (button 3).
		--
		-- pressed: indicates the state of the button:
		--
		-- 0 - mouse button was released;
		-- 1 - mouse button was pressed.
		-- 
		-- x, y: position in the canvas where the event has occurred, in pixels.
		--
		-- status: status of the mouse buttons and some keyboard keys at the 
		-- moment the event is generated. The following macros must be used for 
		-- verification:
		--
		-- Returns: IUP_CLOSE will be processed. On some controls if IUP_IGNORE 
		-- is returned the action is ignored (this is system dependent).
		local
			operation: INTEGER
		do
			cb_flat_button := act

			if cb_flat_button /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "FLAT_BUTTON_CB", "NONEEDED", operation)
		end

	set_cb_flat_focus (act: FUNCTION[TUPLE[IUP_FLAT_TOGGLE, INTEGER], STRING])
		-- Called when the canvas gets or looses the focus. It is called after 
		-- the common callbacks GETFOCUS_CB and KILL_FOCUS_CB.
		-- ih: identifier of the element that activated the event.
		-- focus: is non zero if the canvas is getting the focus, is zero if it 
		-- is loosing the focus.
		local
			operation: INTEGER
		do
			cb_flat_focus := act

			if cb_focus /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "FLAT_FOCUS_CB", "NONEEDED", operation)
		end

	set_cb_flat_enter_window (act: FUNCTION[TUPLE[IUP_FLAT_TOGGLE], STRING])
		-- Action generated when the mouse enters the native element. 
		local
			operation: INTEGER
		do
			cb_flat_enterwindow := act

			if cb_enterwindow /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "FLAT_ENTERWINDOW_CB", "NONEEDED", operation)
		end

	set_cb_flat_leave_window (act: FUNCTION[TUPLE[IUP_FLAT_TOGGLE], STRING])
		-- Action generated when the mouse leaves the native element.
		local
			operation: INTEGER
		do
			cb_flat_leavewindow := act

			if cb_leavewindow /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "FLAT_LEAVEWINDOW_CB", "NONEEDED", operation)
		end

feature {IUP}

	-- Callbacks

	execute_flat_action: STRING
		do
			Result := cb_flat_action.item([Current])
		end

	execute_valuechanged: STRING
		do
			Result := cb_valuechanged.item([Current])
		end	

	execute_flat_button (btn, pressed, x, y: INTEGER; status: STRING): STRING
		do
			Result := cb_flat_button.item([Current, btn, pressed, x, y, status])
		end

	execute_flat_focus (focus: INTEGER): STRING
		do
			Result := cb_flat_focus.item([Current, focus])
		end

	execute_flat_enterwindow: STRING
		do
			Result := cb_flat_enterwindow.item([Current])
		end

	execute_flat_leavewindow: STRING
		do
			Result := cb_flat_leavewindow.item([Current])
		end

feature {}

	cb_flat_action: FUNCTION[TUPLE[IUP_FLAT_TOGGLE], STRING]
	cb_valuechanged: FUNCTION[TUPLE[IUP_FLAT_TOGGLE], STRING]
	cb_flat_button: FUNCTION[TUPLE[IUP_FLAT_TOGGLE, INTEGER, INTEGER, INTEGER, INTEGER, STRING], STRING]
	cb_flat_focus: FUNCTION[TUPLE[IUP_FLAT_TOGGLE, INTEGER], STRING]
	cb_flat_enterwindow: FUNCTION[TUPLE[IUP_FLAT_TOGGLE], STRING]
	cb_flat_leavewindow: FUNCTION[TUPLE[IUP_FLAT_TOGGLE], STRING]

	-- Internals
	
	int_flat_toggle (t: POINTER): POINTER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupFlatToggle"
         }"
      end

	-- Validations

	is_valid_state (value: STRING): BOOLEAN
		do
			if value.is_equal("ON") or
				value.is_equal("OFF") or
				value.is_equal("NOTDEF") then
				Result := True
			else
				Result := False
			end
		end
	
end -- class IUP_FLAT_TOGGLE

-- The MIT License (MIT)

-- Copyright (c) 2019, 2022 by German A. Arias

-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in 
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-- SOFTWARE.
